﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using JigLibX.Math;
using JigLibX.Physics;
using JigLibX.Geometry;
using JigLibX.Collision;

namespace ProceduralGolf
{
    class PowerBar
    {
        public float Power { get; set; }

        public Vector2 Position { get; set; }

        private const float MAX = 1000.0f;

        private GraphicsDevice graphicsDevice;

        public Texture2D powerBlock;
        int nParts;
        int innerRadius = 100;
        int outerRadius = 300;
        int radius;
        SpriteBatch spriteBatch;

        TextureBlurrer textureBlurrer;


        public PowerBar(Game game)
        {
            this.graphicsDevice = game.GraphicsDevice;
            spriteBatch = new SpriteBatch(graphicsDevice);
            textureBlurrer = new TextureBlurrer(game);
        }

        ~PowerBar()
        {
            spriteBatch.Dispose();
        }

        public void calculatePower(float millis)
        {
            Power = 1 - ((Math.Abs(MAX - millis % (2 * MAX))) / MAX);
            //Power = 0.5f + 0.5f * Power;
            //Power = (float)Math.Pow(Power, 2);
        }

        public void reset() { Power = 0.0f; }

        public float segmentLength(float radius, int parts)
        {
            float angle = MathHelper.TwoPi / parts;
            Vector2 v0 = new Vector2(radius, 0.0f);
            Vector2 v1 = new Vector2((float)Math.Cos(angle) * radius, (float)Math.Sin(angle) * radius);
            return Vector2.Distance(v0, v1);
        }

        public Texture2D generatePowerBarBlock(int outerLength, int innerLength, int width)
        {
            int offset = 10;
            Texture2D tex = new Texture2D(graphicsDevice, width + 2*offset, outerLength + 2*offset);

            Color[] data = new Color[tex.Width * tex.Height];

            int innerTop = (outerLength - innerLength) / 2;
            int innerBottom = innerTop + innerLength;

            Color fillColor1 = Color.LightGray;
            Color fillColor2 = Color.White;
            Color borderColor = Color.Black;

            for (int x = 1; x < width - 1; x++)
            {

                int yTop = (int)Math.Floor(MathHelper.Lerp(innerTop, 0.0f, (float)x / (float)width));
                int yBottom = (int)Math.Ceiling(MathHelper.Lerp(innerBottom - 1, outerLength - 1, (float)x / (float)width));
                Color fillColor = Color.Lerp(fillColor1, fillColor2, (float)x / (float)width);
                for (int y = yTop + 1; y < yBottom; y++)
                {
                    data[(y+offset) * tex.Width + (x+offset)] = fillColor;
                }
                data[(yTop+offset) * tex.Width + (x+offset)] = borderColor;
                data[(yBottom+offset) * tex.Width + (x+offset)] = borderColor;
            }
            for (int y = 0; y < outerLength; y++) data[(y+offset) * tex.Width + (tex.Width - 1) - offset] = borderColor;
            for (int y = innerTop; y < innerBottom; y++) data[(y+offset) * tex.Width + offset] = borderColor;

            tex.SetData(data);

            return tex;
        }

        public void generatePowerBar(int parts)
        {
            int innerLength = (int)segmentLength(innerRadius, parts);
            int outerLength = (int)segmentLength(outerRadius, parts);

            float angle = MathHelper.TwoPi / parts;
            Vector2 v0 = new Vector2(innerRadius, 0.0f);
            Vector2 v1 = new Vector2((float)Math.Cos(angle) * innerRadius, (float)Math.Sin(angle) * innerRadius);
            Vector2 p0 = (v0 + v1) / 2;

            v0 = new Vector2(outerRadius, 0.0f);
            v1 = new Vector2((float)Math.Cos(angle) * outerRadius, (float)Math.Sin(angle) * outerRadius);
            Vector2 p1 = (v0 + v1) / 2;

            int width = (int)Vector2.Distance(p0, p1);

            powerBlock = textureBlurrer.blur(generatePowerBarBlock(outerLength, innerLength, width), 1);

            nParts = parts;
            radius = (int)p0.Length();
        }

        public void Draw()
        {
            spriteBatch.Begin();

            float angle = 0.0f;
            float delta = -MathHelper.TwoPi / nParts;
            angle = delta / 2;
            //spriteBatch.Draw(powerBlock, rect, Color.Red);
            Color color1 = Color.LawnGreen;
            Color color2 = Color.Red;



            int litParts = (int)Math.Round(nParts * Power);
            for (int i = 0; i < nParts; i++)
            {
                float currentAngle = angle + delta * i;
                Color color = Color.Lerp(color1, color2, (float)Math.Pow((float)i / (float)nParts, 2));
                if (i >= litParts)
                    color.A -= 128;
                spriteBatch.Draw(powerBlock, Position, null, color, currentAngle, new Vector2(-radius, powerBlock.Height / 2), 0.2f, SpriteEffects.None, 1);

            }
            spriteBatch.End();
        }

    }
}
